import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;//导入包
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Calendar;
import java.util.Date;

/**
 * Java中常见的时间类
 *
 * 1.Date
 *  Date类是一个过时的类，不推荐使用。
 *  Date类是Java早期的日期时间类之一，用于表示指定的瞬间，精确到毫秒级别。然而，由于它存在线程安全问题和格式化等方面的限制，因此在Java 8及以后的版本中，已经不被推荐使用。
 *
 * 2.LocalDate
 * LocalDate类只包含日期信息，没有时间和时区，用于存储日期，比如生日、纪念日等。
 * 它是不可变对象，线程安全，并支持加减天数、星期几等运算。
 * LocalDate类是Java 8新引入的日期类，用于表示日期信息，即年月日等，没有时区。
 * 与Date类相比，它是不可变对象、线程安全的，并提供许多方便的方法来进行日期操作。
 *
 * 3.LocalDateTime
 * LocalDateTime类包含日期和时间，对应的是系统本地时间，精确到纳秒级别，但并没有包含时区信息。
 * 它也是不可变对象，并提供了加减天数、小时数等运算。
 * LocalTime类也是Java 8新引入的时间类，用于表示时间，即小时数、分钟数、秒数和纳秒数等。
 * 与Date类相似，它是不可变对象、线程安全的，同时还提供了很多方便的操作方法。
 *
 * 4.LocalTime
 * LocalTime类则只包含时间信息，没有日期和时区
 * 它也是不可变对象，线程安全，并支持加减时间和分钟等运算。
 * LocalDateTime类则可以看作是LocalDate和LocalTime的结合体，包含日期和时间信息，但没有时区。
 * 它也是不可变对象、线程安全的，并提供了丰富的日期和时间操作方法。
 */

public class Main {
    public static void main(String[] args) {
        /**
         * 1.获取时间戳
         * 2.字符串转时间
         * 3.时间转字符串
         * 4.时间加减
         */
        //DateClass();
        //LocalDateClass();
        //LocalTimeClass();
        LocalDateTimeClass();
    }

    public static void DateClass() {
        Date now=new Date();//获取当前的时间
        long timeStamp=now.getTime();

        //根据当前时间获取时间戳 1970-01-01 0:0:0到现在的毫秒数
        //getTime()==System.currentTimeMillis()
        System.out.println("1.时间戳："+timeStamp);

        SimpleDateFormat t=new SimpleDateFormat("yyyy-MM-dd");
        String date_str=t.format(timeStamp);//将时间戳转换为日期字符串
        Date d=null;
        try {
            d=t.parse(t.format(timeStamp));//将字符串转换为了日期类型

        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        System.out.println("2.时间戳转日期："+t.format(d));
        System.out.println("3.日期字符串："+t.format(timeStamp));

        /*日期类型加减*/
        Calendar calen=Calendar.getInstance();/*调用工具类import java.util.Calendar*/
        calen.setTime(d);
        calen.add(calen.DATE,30);
        d=calen.getTime();
        System.out.println("4.日期+30天"+t.format(d));


    }

    public static void LocalDateClass() {
        LocalDate date=LocalDate.now();//获取当前日期...
        /*将LocaDate转换为时间戳*/

        /*atStartOfDay()方法将其转换为当天零点的时间*/
        /*ZoneId.systemDefault() 获取当前系统默认时区的ZoneId对象*/
        /*toInstant()方法会将该Instant对象转换为对应的UTC（协调世界时）时刻，然后返回一个Instant对象*/
        /*toEpochMilli()方法则会将UTC时刻转换为自1970年1月1日00:00:00以来的毫秒数，返回一个long类型的数值*/
        long timeStamp=date.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli();
        System.out.println("时间戳："+timeStamp);

        LocalDate date_str=LocalDate.parse("2023-12-01");
        System.out.println("时间转字符串："+date_str);

        /*LocalDate转特定格式的字符串*/
        DateTimeFormatter date_for=DateTimeFormatter.ofPattern("MM/dd/yyyy");
        String date1=date_for.format(date);
        System.out.println("特定格式输出："+date1);

        /*LocalDate日期加减*/
         LocalDate date_plusDay=date.plusDays(30);//日期+15天
         LocalDate date_plusMonth=date_plusDay.plusMonths(2);//日期+2月
        System.out.println("日期加减(plus..):"+date_plusMonth);
    }

    public static void LocalTimeClass() {
        LocalTime time=LocalTime.now();/*获取当前时间*/
        System.out.println("时间戳：LocalTime不能直接转换为时间戳，因为LocalTime只包含时间信息，不包含日期信息");

        //字符串转时间 格式 时:分:秒
        LocalTime timeTest1=LocalTime.parse("15:13:12");
        System.out.println("字符串转Time："+timeTest1);


        // DateTimeFormatter的作用等价于SimpleDateFormat
        // DateTimeFormatter 是线程安全的类，在多线程中对LocalDate,LocalDateTime,LocalTime进行格式化
        // SimpleDateFormat 是线程不安全的类，对java.util.Date类进行格式化转换
        // 利用ofPattern()方法进行转换 HH小时 mm分钟 ss秒数 其实就是英语单词的首字母
        DateTimeFormatter tiem_form=DateTimeFormatter.ofPattern("HH点mm分ss秒");
        LocalTime time_str=LocalTime.parse("15点15分15秒",tiem_form);
        System.out.println("字符串格式转Time："+time_str);
    }
    public static void LocalDateTimeClass() {
    //mysql-connector 8.x的版本中，数据库中的date会映射为java中的LocalDateTime类型
    //如果mysql-connector 5.x的版本，数据库中的date映射为java中的java.sql.Timestamp; 时间戳
        LocalDateTime dateTime=LocalDateTime.now();//获取当前时间

        DateTimeFormatter date_Formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        long instant=dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();//转换为时间戳
        System.out.println("时间戳："+instant);

        //字符串转LocalDateTime
        String str="2003-09-15 00:00:00";
        //emporalAccessor是Java 8中新引入的日期时间API中的一个通用接口，它提供了一些列方法可用于获取和修改各种日期和时间字段的信息
        //可在不知道具体日期时间类型的情况下进行通用处理。

        TemporalAccessor temporalAccessor=date_Formatter.parse(str);
        LocalDateTime time_s=LocalDateTime.from(temporalAccessor);//利用LocalDateTime的form方法进行转换
        System.out.println("字符串转LocalDateTime："+time_s);

        //LocalDateTime转字符串
        String str_time=dateTime.format(date_Formatter);
        System.out.println("LocalDateTime转字符串："+str_time);

    }

}